﻿#ifndef CMD_SPARROW_HEAD_FILE
#define CMD_SPARROW_HEAD_FILE

#include "biostream.h"
//#include "../../Common/CommonMsg.h"
//#include <string>
//#pragma pack(1)
//////////////////////////////////////////////////////////////////////////
//公共宏定义

#define KIND_ID							984									//游戏 I D
#define MAX_PLAYER						4									//游戏人数
#define MAX_PLAYER						4									//游戏人数
#define GAME_NAME						TEXT("武汉麻将(开口番)")				//游戏名字
#define GAME_GENRE						(GAME_GENRE_GOLD|GAME_GENRE_MATCH)	//游戏类型

//游戏状态
#define GS_MJ_FREE						GS_FREE								//空闲状态
#define GS_MJ_PLAY						(GS_PLAYING+1)						//游戏状态
#define GS_MJ_HAI_DI					(GS_PLAYING+2)						//海底状态

#define ID_IPHONE_OLD					11									//老手机版本号
#define GAME_OPERATION_TIME				20									//操作超时时间
#define MAX_CHAT_LEN					128									//聊天长度

//游戏类型
#define GAME_GENRE_SCORE				0x0001								//点值类型
#define GAME_GENRE_GOLD					0x0002								//金币类型
#define GAME_GENRE_MATCH				0x0004								//比赛类型
#define GAME_GENRE_EDUCATE				0x0008								//训练类型

//游戏状态
#define GS_FREE							0									//空闲状态
#define GS_PLAYING						100									//游戏状态
#define GS_END							103									//小结算状态

//定义 | 四喜
#define HAVE_SIXI_HU				(true)

//定义 | 缺一色
#define HAVE_QUE_YISE_HU			(true)

//定义 | 板板胡
#define HAVE_BANBAN_HU				(true)

//定义 | 六六顺
#define HAVE_LIULIU_HU				(true)

//定义 | 清一色
#define HAVE_QING_YISE_HU			(true)

//定义 | 七小对
#define HAVE_FENG_YI_SE				(true)

//定义 | 豪华对
#define HAVE_HAO_HUA_DUI_HU			(true)

//定义 | 将将胡
#define HAVE_JIANG_JIANG_HU			(true)

//定义 | 风一色胡
#define HAVE_FENG_YISE_HU			(true)

//定义 | 全求人胡
#define HAVE_QUAN_QIU_REN			(true)

//定义 | 碰碰胡
#define HAVE_PENG_PENG_HU			(true)

//海底胡牌
#define HAVE_HAI_DI_HU				(true)

//定义 |抢杠
#define HAVE_QIANG_GANG_HU			(true)

//定义 |杠上开花
#define HAVE_GANG_SHANG_KAI_HUA		(true)


//定义 | 地胡
#define HAVE_DI_HU					(true)

//定义 | 天胡
#define HAVE_TIAN_HU				(true)

//定义 | 自摸加1
#define HAVE_ZIMO_JIAO_1			(false)


#ifdef HAVE_ZIMO_JIAO_1
	#define NumX(n) (n)
#else
	#define NumX(n) (n-1)
#endif

 
//模块定义
#ifdef _DEBUG
#define SERVICE_DLL_NAME	TEXT("GameServiceWHMJD.dll")				//组件 DLL 名字
#else
#define SERVICE_DLL_NAME	TEXT("GameServiceWHMJ.dll")					//组件 DLL 名字
#endif


//////////////////////////////////////////////////////////////////////////
//双十一活动
// typedef struct DoubleEleven
// {
// 	BYTE				ucWinTime;				// 胜利局数
// 	BYTE				ucGameTime;				// 游戏局数
// 	BYTE				ucCompleteReward;		// 赢多少局获得奖励
// 	BYTE				ucCompleteLimit;		// 多少局内完成
// 	BYTE				ucOpentime[2];			// 每日开启时间
// 	bool				bCompleteTast;			// 是否完成任务
// 
// }CMD_DoubleEleven;

// struct CMD_DiceTask
// {
// 	BYTE				ucDiceCnt;				// 骰子个数
// 	BYTE				ucObtainDice;			// 本次获得个数
// 	bool				bClose;
// };


//组合子项
struct CMD_WeaveItem
{
	BYTE							cbWeaveKind;						//组合类型
	BYTE							cbCenterCard;						//中心扑克
	BYTE							cbPublicCard;						//公开标志
	WORD							wProvideUser;						//供应用户
};

//听牌蕃数
// struct tagTingFan
// {
// 	BYTE							cbHongZhong;						//红中个数
// 	BYTE							cbLaiZi;							//癞子个数
// 	BYTE							cbMingGang;							//明杠个数
// 	BYTE							cbAnGang;							//暗杠个数
// 	bool							bIsYingHu;							//是否硬胡
// 	bool							bIsZhuangJia;						//是否庄家
// };

//听牌结果
struct tagTingCardResult
{
	bool							bTingIndex[34];						//听牌索引
	int 							cbTingNumber[34];					//听牌数量
	int 							cbTingFanShu[34];					//听牌蕃数
};

//牌
struct tagCard
{
	BYTE							cbHDCard;							//海底扑克
	int								nIndex;								//海底牌索引
	int								nUserIndex;							//海底牌玩家索引
	void reset() { memset(this, 0, sizeof(*this)); }
	tagCard() { reset(); }
	friend bostream& operator<<(bostream& bos,const tagCard& pl)
	{
		bos << pl.cbHDCard;
		bos << pl.nIndex;
		bos << pl.nUserIndex;
		return bos;
	}
	friend bistream& operator>>(bistream& bis,tagCard& pl)
	{
		pl.reset();
		bis >> pl.cbHDCard;
		bis >> pl.nIndex;
		bis >> pl.nUserIndex;

		return bis;
	}

};
//海底扑克
struct tagHDCard
{
	tagCard							HDCard[14];							//海底扑克
	bool							bVisible[14];						//扑克是否翻开
};

//趣语
struct tagFunSound
{
	BYTE							cbFunSoundIndex;					//趣语索引
	int								nSoundKindIndex;					//语言种类索引
};

// struct tagUserInfo
// {
//     std::string							strName;							//用户名字
// 	WORD								wFaceID;							//头像索引
// 	BYTE								cbGender;							//用户性别
// };
//////////////////////////////////////////////////////////////////////////
//服务器命令结构

#define SUB_S_GAME_START			100									//游戏开始
#define SUB_S_OUT_CARD				101									//出牌命令
#define SUB_S_SEND_CARD				102									//发送扑克
#define SUB_S_OPERATE_NOTIFY		103									//操作提示
#define SUB_S_OPERATE_RESULT		104									//操作命令
#define SUB_S_GAME_END				105									//游戏结束
#define SUB_S_HD					106									//海底提示
#define SUB_S_HD_CHANGE				107									//海底提示
#define SUB_S_TRUSTEE				108									//托管操作
#define SUB_S_SENFUNSOUND			109									//发送趣语
#define SUB_S_GAME_TASK				110									//发送任务
#define SUB_S_GAMEEND_TASK			111									//发送任务
//#define SUB_S_GAMEELN_TASK			112									//十一任务
//#define SUB_S_DICE_TASK				113									//大富翁
#define SUB_S_GAMEELN_TASK			112									//光棍节活动
#define SUB_S_GAME_CONFIG			113									//跑跑三国配置
#define SUB_S_GAME_RESULT			114									//跑跑三国结算

#define SUB_S_GAME_BALANCE_GAME		115									// 总结算
#define SUB_S_GAME_BALANCE_GAME_V2	116									// 总结算V2

//游戏状态		// 手机兼容
struct CMD_S_StatusFree
{
	int							lCellScore;							//基础金币
	WORD							wBankerUser;						//庄家用户
	BYTE							ucGameType;							//游戏类型 0:7pi4lai, 1:11pi4lai
	bool							bKaiKou;							//确定开口口口
	bool							bRenWuAble;							//任务是否开启

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_StatusFree() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_StatusFree& pl)
	{
		bos << pl.lCellScore;
		bos << pl.wBankerUser;
		bos << pl.ucGameType;
		bos << pl.bRenWuAble;
		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_StatusFree& pl)
	{
		pl.reset();
		bis >> pl.lCellScore;
		bis >> pl.wBankerUser;
		bis >> pl.ucGameType;
		bis >> pl.bRenWuAble;

		return bis;
	}
};

// 服务器发给客户端 总结算
struct CMD_S_BALANCE_GAME_V2
{
	enum {XY_ID = SUB_S_GAME_BALANCE_GAME_V2};
	
	unsigned int					userid; // userid房主
	int								lGameScore[MAX_PLAYER];				//游戏积分
	WORD							wChiHuUserCount[MAX_PLAYER];					//胡牌总数
	WORD							wProvideUserCount[MAX_PLAYER];					//点炮次数
	WORD							wFXMaxUserCount[MAX_PLAYER];					//最大翻数
	WORD							wHHuUserCount[MAX_PLAYER];					//大胡次数
	BYTE							curTotalCount;						//当前总局数 
	WORD							wUserEndState[MAX_PLAYER];			//总结算时玩家状态：0正常，1解散，2离线

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_BALANCE_GAME_V2() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_BALANCE_GAME_V2& pl)
	{
		bos << pl.userid;
		bos.write((char*)pl.lGameScore, sizeof(pl.lGameScore));
		bos.write((char*)pl.wChiHuUserCount, sizeof(pl.wChiHuUserCount));
		bos.write((char*)pl.wProvideUserCount, sizeof(pl.wProvideUserCount));
		bos.write((char*)pl.wFXMaxUserCount, sizeof(pl.wFXMaxUserCount));
		bos.write((char*)pl.wHHuUserCount, sizeof(pl.wHHuUserCount));
		bos << pl.curTotalCount;
		bos.write((char*)pl.wUserEndState, sizeof(pl.wUserEndState));
		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_BALANCE_GAME_V2& pl)
	{
		pl.reset();
		bis >> pl.userid;
		bis.read((char*)pl.lGameScore, sizeof(pl.lGameScore));
		bis.read((char*)pl.wChiHuUserCount, sizeof(pl.wChiHuUserCount));
		bis.read((char*)pl.wProvideUserCount, sizeof(pl.wProvideUserCount));
		bis.read((char*)pl.wFXMaxUserCount, sizeof(pl.wFXMaxUserCount));
		bis.read((char*)pl.wHHuUserCount, sizeof(pl.wHHuUserCount));
		bis >> pl.curTotalCount;
		bis.read((char*)pl.wUserEndState, sizeof(pl.wUserEndState));

		return bis;
	}
};

//游戏状态
struct CMD_S_StatusFreePC
{
	int								lCellScore;							//基础金币
	WORD							wBankerUser;						//庄家用户
	BYTE							ucGameType;							//游戏类型		//0是7皮
	bool							bKaiKou;							//确定开口口口
	bool							bRenWuAble;							//任务是否开启
};


//游戏状态		// 手机兼容
struct CMD_S_StatusPlay
{
	//游戏变量
	int							lCellScore;							//单元积分
	WORD							wSiceCount;							//骰子点数
	WORD							wBankerUser;						//庄家用户
	WORD							wCurrentUser;						//当前用户

	//状态变量
	BYTE							cbActionCard;						//动作扑克
	BYTE							cbActionMask;						//动作掩码
	BYTE							cbLeftCardCount;					//剩余数目

	//出牌信息
	WORD							wOutCardUser;						//出牌用户
	BYTE							cbOutCardData;						//出牌扑克
	BYTE							cbDiscardCount[4];					//丢弃数目
	BYTE							cbDiscardCard[4][55];				//丢弃记录

	//扑克数据
	BYTE							cbCardCount;						//扑克数目
	BYTE							cbCardData[14];						//扑克列表

	//组合扑克
	BYTE							cbWeaveCount[4];					//组合数目
	CMD_WeaveItem					WeaveItemArray[4][4];				//组合扑克

	BYTE                            cbPiZiCard;                         //皮子
	BYTE							ucGameType;							//游戏类型
	bool							bKaiKou;							//确定开口口口
	bool							bRenWuAble;							//任务是否开启

	BYTE							nPiGangCount[4];					//皮子癞子个数
	BYTE							nLaiGangCount[4];					//癞子癞子个数

	BYTE							cbTheOrder;							//当前是第几局

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_StatusPlay() { reset(); }
	friend bostream& operator<<(bostream& bos, const CMD_S_StatusPlay& pl)
	{
		bos << pl.lCellScore;
		bos << pl.wSiceCount;
		bos << pl.wBankerUser;
		bos << pl.wCurrentUser;
		bos << pl.cbActionCard;

		bos << pl.cbActionMask;
		bos << pl.cbLeftCardCount;
		bos << pl.wOutCardUser;
		bos << pl.cbOutCardData;
		bos.write((char*)pl.cbDiscardCount, sizeof(pl.cbDiscardCount));
		bos.write((char*)pl.cbDiscardCard, sizeof(pl.cbDiscardCard));

		bos << pl.cbCardCount;
		bos.write((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bos.write((char*)pl.cbWeaveCount, sizeof(pl.cbWeaveCount));
		bos.write((char*)pl.WeaveItemArray, sizeof(pl.WeaveItemArray));
		bos << pl.cbPiZiCard;
		bos << pl.ucGameType;
		bos << pl.bKaiKou;
		bos << pl.bRenWuAble;
		bos.write((char*)pl.nPiGangCount, sizeof(pl.nPiGangCount));
		bos.write((char*)pl.nLaiGangCount, sizeof(pl.nLaiGangCount));

		bos << pl.cbTheOrder;

		return bos;
	}
	friend bistream& operator>>(bistream& bis, CMD_S_StatusPlay& pl)
	{
		pl.reset();
		bis >> pl.lCellScore;
		bis >> pl.wSiceCount;
		bis >> pl.wBankerUser;
		bis >> pl.wCurrentUser;
		bis >> pl.cbActionCard;

		bis >> pl.cbActionMask;
		bis >> pl.cbLeftCardCount;
		bis >> pl.wOutCardUser;
		bis >> pl.cbOutCardData;
		bis.read((char*)pl.cbDiscardCount, sizeof(pl.cbDiscardCount));
		bis.read((char*)pl.cbDiscardCard, sizeof(pl.cbDiscardCard));

		bis >> pl.cbCardCount;
		bis.read((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bis.read((char*)pl.cbWeaveCount, sizeof(pl.cbWeaveCount));
		bis.read((char*)pl.WeaveItemArray, sizeof(pl.WeaveItemArray));
		bis >> pl.cbPiZiCard;
		bis >> pl.ucGameType;
		bis >> pl.bKaiKou;
		bis >> pl.bRenWuAble;
		bis.read((char*)pl.nPiGangCount, sizeof(pl.nPiGangCount));
		bis.read((char*)pl.nLaiGangCount, sizeof(pl.nLaiGangCount));

		bis >> pl.cbTheOrder;
		return bis;
	}
};

//游戏状态 
struct CMD_S_StatusPlayPC
{
	//游戏变量
	float							lCellScore;							//单元积分
	WORD							wSiceCount;							//骰子点数
	WORD							wBankerUser;						//庄家用户
	WORD							wCurrentUser;						//当前用户

	//状态变量
	BYTE							cbActionCard;						//动作扑克
	BYTE							cbActionMask;						//动作掩码
	BYTE							cbLeftCardCount;					//剩余数目

	//出牌信息
	WORD							wOutCardUser;						//出牌用户
	BYTE							cbOutCardData;						//出牌扑克
	BYTE							cbDiscardCount[4];					//丢弃数目
	BYTE							cbDiscardCard[4][55];				//丢弃记录

	//扑克数据
	BYTE							cbCardCount;						//扑克数目
	BYTE							cbCardData[14];						//扑克列表

	//组合扑克
	BYTE							cbWeaveCount[4];					//组合数目
	CMD_WeaveItem					WeaveItemArray[4][4];				//组合扑克

	BYTE                            cbPiZiCard;                         //皮子
	BYTE							ucGameType;							//游戏类型
	bool							bKaiKou;							//确定开口口口
	bool							bRenWuAble;							//任务是否开启

	BYTE							nPiGangCount[4];					//皮子癞子个数
	BYTE							nLaiGangCount[4];					//癞子癞子个数
};


//海底状态
struct CMD_S_StatusHiDi
{
	//游戏变量
	int							lCellScore;							//单元积分
	WORD							wBankerUser;						//庄家用户
	WORD							wCurrentUser;						//当前用户

	//状态变量
	BYTE							cbLeftCardCount;					//剩余数目

	//出牌信息
	BYTE							cbDiscardCount[4];					//丢弃数目
	BYTE							cbDiscardCard[4][55];				//丢弃记录

	//扑克数据
	BYTE							cbCardCount;						//扑克数目
	BYTE							cbCardData[14];						//扑克列表
	BYTE							cbHiDiCardData[14];					//海底扑克
	tagCard							HDCard[MAX_PLAYER];				//海底牌记录

	//组合扑克
	BYTE							cbWeaveCount[4];					//组合数目
	CMD_WeaveItem					WeaveItemArray[4][4];				//组合扑克

	BYTE                            cbPiZiCard;                         //皮子
	BYTE							ucGameType;							//游戏类型
	bool							bKaiKou;							//确定开口口口
	bool							bRenWuAble;							//任务是否开启

	BYTE							nPiGangCount[4];					//皮子癞子个数
	BYTE							nLaiGangCount[4];					//癞子癞子个数
	int								iRemainTime;						//操作剩余时间 （海底捞

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_StatusHiDi() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_StatusHiDi& pl)
	{
		bos << pl.lCellScore;
		bos << pl.wBankerUser;
		bos << pl.wCurrentUser;
		bos << pl.cbLeftCardCount;
		bos.write((char*)pl.cbDiscardCount, sizeof(pl.cbDiscardCount));
		bos.write((char*)pl.cbDiscardCard, sizeof(pl.cbDiscardCard));
		bos << pl.cbCardCount;
		bos.write((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bos.write((char*)pl.cbHiDiCardData, sizeof(pl.cbHiDiCardData));
		bos.write((char*)pl.HDCard, sizeof(pl.HDCard));
		bos.write((char*)pl.cbWeaveCount, sizeof(pl.cbWeaveCount));
		bos.write((char*)pl.WeaveItemArray, sizeof(pl.WeaveItemArray));

		bos << pl.cbPiZiCard; 
		bos << pl.ucGameType;	
		bos << pl.bKaiKou;	
		bos << pl.bRenWuAble;	
		bos.write((char*)pl.nPiGangCount, sizeof(pl.nPiGangCount));
		bos.write((char*)pl.nLaiGangCount, sizeof(pl.nLaiGangCount));
		
		bos << pl.iRemainTime;	

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_StatusHiDi& pl)
	{
		pl.reset();
		bis >> pl.lCellScore;
		bis >> pl.wBankerUser;
		bis >> pl.wCurrentUser; 
		bis >> pl.cbLeftCardCount;
		bis.read((char*)pl.cbDiscardCount, sizeof(pl.cbDiscardCount));
		bis.read((char*)pl.cbDiscardCard, sizeof(pl.cbDiscardCard));
		bis >> pl.cbCardCount;
		bis.read((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bis.read((char*)pl.cbHiDiCardData, sizeof(pl.cbHiDiCardData));
		bis.read((char*)pl.HDCard, sizeof(pl.HDCard));
		bis.read((char*)pl.cbWeaveCount, sizeof(pl.cbWeaveCount));
		bis.read((char*)pl.WeaveItemArray, sizeof(pl.WeaveItemArray));

		bis >> pl.cbPiZiCard; 
		bis >> pl.ucGameType;	
		bis >> pl.bKaiKou;	
		bis >> pl.bRenWuAble;	
		bis.read((char*)pl.nPiGangCount, sizeof(pl.nPiGangCount));
		bis.read((char*)pl.nLaiGangCount, sizeof(pl.nLaiGangCount));

		bis >> pl.iRemainTime;	
		return bis;
	}
};

//海底状态
struct CMD_S_StatusHiDiPC
{
	//游戏变量
	float							lCellScore;							//单元积分
	WORD							wBankerUser;						//庄家用户
	WORD							wCurrentUser;						//当前用户

	//状态变量
	BYTE							cbLeftCardCount;					//剩余数目

	//出牌信息
	BYTE							cbDiscardCount[4];					//丢弃数目
	BYTE							cbDiscardCard[4][55];				//丢弃记录

	//扑克数据
	BYTE							cbCardCount;						//扑克数目
	BYTE							cbCardData[14];						//扑克列表
	BYTE							cbHiDiCardData[14];					//海底扑克
	tagCard							HDCard[MAX_PLAYER];				//海底牌记录

	//组合扑克
	BYTE							cbWeaveCount[4];					//组合数目
	CMD_WeaveItem					WeaveItemArray[4][4];				//组合扑克

	BYTE                            cbPiZiCard;                         //皮子
	BYTE							ucGameType;							//游戏类型
	bool							bKaiKou;							//确定开口口口
	bool							bRenWuAble;							//任务是否开启

	BYTE							nPiGangCount[4];					//皮子癞子个数
	BYTE							nLaiGangCount[4];					//癞子癞子个数
	int								iRemainTime;						//操作剩余时间 （海底捞
};

//游戏开始
struct CMD_S_GameStart
{
	enum {XY_ID = SUB_S_GAME_START};

	WORD							wSiceCount;							//骰子点数
	WORD							wBankerUser;						//庄家用户
	WORD							wCurrentUser;						//当前用户
	BYTE							cbUserAction;						//用户动作
	BYTE							cbCardData[14];						//扑克列表
	BYTE                            cbMagicCard;

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_GameStart() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_GameStart& pl)
	{
		bos << pl.wSiceCount;
		bos << pl.wBankerUser;
		bos << pl.wCurrentUser;
		bos << pl.cbUserAction;
		bos.write((char*)pl.cbCardData, sizeof(pl.cbCardData));

		bos << pl.cbMagicCard;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_GameStart& pl)
	{
		pl.reset();
		bis >> pl.wSiceCount;
		bis >> pl.wBankerUser;
		bis >> pl.wCurrentUser;
		bis >> pl.cbUserAction;
		bis.read((char*)pl.cbCardData, sizeof(pl.cbCardData));

		bis >> pl.cbMagicCard;
		return bis;
	}
};

//出牌命令
struct CMD_S_OutCard
{
	enum {XY_ID = SUB_S_OUT_CARD}; 

	WORD							wOutCardUser;						//出牌用户
	BYTE							cbOutCardData;						//出牌扑克

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_OutCard() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_OutCard& pl)
	{
		bos << pl.wOutCardUser;
		bos << pl.cbOutCardData;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_OutCard& pl)
	{
		pl.reset();
		bis >> pl.wOutCardUser;
		bis >> pl.cbOutCardData;
		return bis;
	}

};

//发送扑克
struct CMD_S_SendCard
{
	enum {XY_ID = SUB_S_SEND_CARD}; 

	BYTE							cbCardData;							//扑克数据
	BYTE							cbActionMask;						//动作掩码
	WORD							wCurrentUser;						//当前用户
	bool							bIsHD;								//是否海底
	bool                            bIsGang;                            //是否是杠牌后发牌
	bool							bEnjoinHu;							//是否4番下禁止胡

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_SendCard() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_SendCard& pl)
	{
		bos << pl.cbCardData;
		bos << pl.cbActionMask;
		bos << pl.wCurrentUser;
		bos << pl.bIsHD;
		bos << pl.bIsGang;
		bos << pl.bEnjoinHu;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_SendCard& pl)
	{
		pl.reset();
		bis >> pl.cbCardData;
		bis >> pl.cbActionMask;
		bis >> pl.wCurrentUser;
		bis >> pl.bIsHD;
		bis >> pl.bIsGang;
		bis >> pl.bEnjoinHu;

		return bis;
	}
};

//海底捞
struct CMD_S_SendHD
{
	enum {XY_ID = SUB_S_HD}; 

	BYTE							cbCardData[14];						//海底扑克数据
	WORD							wCurrentUser;						//当前用户

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_SendHD() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_SendHD& pl)
	{
		bos.write((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bos << pl.wCurrentUser;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_SendHD& pl)
	{
		pl.reset();
		bis.read((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bis >> pl.wCurrentUser;

		return bis;
	}
};

//用户托管
struct CMD_S_Trustee
{
	enum {XY_ID = SUB_S_TRUSTEE}; 
	bool							bTrustee;							//是否托管
	WORD							wChairID;							//托管用户

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_Trustee() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_Trustee& pl)
	{
		bos << pl.bTrustee;
		bos << pl.wChairID;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_Trustee& pl)
	{
		pl.reset();
		bis >> pl.bTrustee;
		bis >> pl.wChairID;

		return bis;
	}

};

//发送趣语
struct CMD_S_FunSound
{
	tagFunSound						FunSound;							//选择的趣语和语言种类
	WORD							wChairID;							//发送用户
};

//操作提示
struct CMD_S_OperateNotify
{
	enum {XY_ID = SUB_S_OPERATE_NOTIFY}; 

	WORD							wResumeUser;						//还原用户
	BYTE							cbActionMask;						//动作掩码
	BYTE							cbActionCard;						//动作扑克

	bool							bEnjoinHu;							//是否4番下禁止胡

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_OperateNotify() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_OperateNotify& pl)
	{
		bos << pl.wResumeUser;
		bos << pl.cbActionMask;
		bos << pl.cbActionCard;
		bos << pl.bEnjoinHu;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_OperateNotify& pl)
	{
		pl.reset();
		bis >> pl.wResumeUser;
		bis >> pl.cbActionMask;
		bis >> pl.cbActionCard;
		bis >> pl.bEnjoinHu;

		return bis;
	}
};

//操作命令
struct CMD_S_OperateResult
{
	enum {XY_ID = SUB_S_OPERATE_RESULT}; 

	WORD							wOperateUser;						//操作用户
	WORD							wProvideUser;						//供应用户
	BYTE							cbOperateCode;						//操作代码
	BYTE							cbOperateCard;						//操作扑克
	bool							bHaveGang[MAX_PLAYER];				//是否杠过

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_OperateResult() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_OperateResult& pl)
	{
		bos << pl.wOperateUser;
		bos << pl.wProvideUser;
		bos << pl.cbOperateCode;
		bos << pl.cbOperateCard;

		bos.write((char*)pl.bHaveGang, sizeof(pl.bHaveGang));

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_OperateResult& pl)
	{
		pl.reset();
		bis >>  pl.wOperateUser;
		bis >>  pl.wProvideUser;
		bis >>  pl.cbOperateCode;
		bis >>  pl.cbOperateCard;

		bis.read((char*)pl.bHaveGang, sizeof(pl.bHaveGang));

		return bis;
	}
};

//游戏结束
struct CMD_S_GameEnd
{
	enum {XY_ID = SUB_S_GAME_END}; 

	BYTE							cbChiHuCard;						//吃胡扑克
	bool                            bKaiKou;                          	//标记是开口还是口口
	WORD							wProvideUser;						//点炮用户
	bool							bTaskFinished;						//第三期任务完成
	int								lGameScore[4];						//游戏积分
	int								lGameAdjustScore[4];				//修订游戏积分
	
	BYTE							cbCardCount[4];						//扑克数目
	BYTE							cbCardData[4][14];					//扑克数据
	char							strEnd[100];                        //胡牌信息
	BYTE							bBirdCard;							//鸟牌
	WORD							bBirdUser;							//中鸟玩家
	int								lTax;								//游戏税收
	WORD							wChiHuUserCount;					//胡牌总数
	bool							bIsQuit;							//是否强退
	WORD                            wWinner;                            //胡牌玩家

	int								lBaseScore; 						//基础分
	WORD							wOperateCount[4];    				//开口次数
	WORD							wShowGangCount[4];    				//明杠次数
	WORD							wHideGangCount[4];    				//暗杠次数
	WORD							wHongzhongGangCount[4];    			//红中杠次数
	WORD							wFaCaiGangCount[4];    				//发财杠次数
	WORD							wMagicGangCount[4];    				//赖子杠次数
	WORD							wMagicOutCount[4];    				//丢赖子的个数
	WORD							wMaxFSCount[4];    					//用户翻数
	WORD                            wContractor;                        //承包用户

	bool                            bHardChiHu;                         //标记是否是硬胡

	BYTE							cbBigHuKind;						//标记大胡类型
	BYTE							cbFengDingKind[4];					//封顶类型
	BYTE							cbTheOrder;							//第几局结算
	BYTE							cbEndStatus;						//表示是哪种结束方式：0正常 1游戏解散 2玩家强退

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_GameEnd() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_GameEnd& pl)
	{
		bos << pl.cbChiHuCard;
		bos << pl.bKaiKou;
		bos << pl.wProvideUser;
		bos << pl.bTaskFinished;

		bos.write((char*)pl.lGameScore, sizeof(pl.lGameScore));
		bos.write((char*)pl.lGameAdjustScore, sizeof(pl.lGameAdjustScore));
		bos.write((char*)pl.cbCardCount, sizeof(pl.cbCardCount));
		bos.write((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bos.write((char*)pl.strEnd, sizeof(pl.strEnd));

		bos << pl.bBirdCard;
		bos << pl.bBirdUser;
		bos << pl.lTax;
		bos << pl.wChiHuUserCount;
		bos << pl.bIsQuit;
		bos << pl.wWinner;
		bos << pl.lBaseScore;
		
		bos.write((char*)pl.wOperateCount, sizeof(pl.wOperateCount));
		bos.write((char*)pl.wShowGangCount, sizeof(pl.wShowGangCount));
		bos.write((char*)pl.wHideGangCount, sizeof(pl.wHideGangCount));
		bos.write((char*)pl.wHongzhongGangCount, sizeof(pl.wHongzhongGangCount));
		bos.write((char*)pl.wFaCaiGangCount, sizeof(pl.wFaCaiGangCount));
		bos.write((char*)pl.wMagicGangCount, sizeof(pl.wMagicGangCount));
		bos.write((char*)pl.wMagicOutCount, sizeof(pl.wMagicOutCount));
		bos.write((char*)pl.wMaxFSCount, sizeof(pl.wMaxFSCount));

		bos << pl.wContractor;
		bos << pl.bHardChiHu;
		bos << pl.cbBigHuKind;

		bos.write((char*)pl.cbFengDingKind, sizeof(pl.cbFengDingKind));

		bos << pl.cbTheOrder;
		bos << pl.cbEndStatus;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_GameEnd& pl)
	{
		pl.reset();
		bis >> pl.cbChiHuCard;
		bis >> pl.bKaiKou;
		bis >> pl.wProvideUser;
		bis >> pl.bTaskFinished;

		bis.read((char*)pl.lGameScore, sizeof(pl.lGameScore));
		bis.read((char*)pl.lGameAdjustScore, sizeof(pl.lGameAdjustScore));
		bis.read((char*)pl.cbCardCount, sizeof(pl.cbCardCount));
		bis.read((char*)pl.cbCardData, sizeof(pl.cbCardData));
		bis.read((char*)pl.strEnd, sizeof(pl.strEnd));

		bis >> pl.bBirdCard;
		bis >> pl.bBirdUser;
		bis >> pl.lTax;
		bis >> pl.wChiHuUserCount;
		bis >> pl.bIsQuit;
		bis >> pl.wWinner;
		bis >> pl.lBaseScore;

		bis.read((char*)pl.wOperateCount, sizeof(pl.wOperateCount));
		bis.read((char*)pl.wShowGangCount, sizeof(pl.wShowGangCount));
		bis.read((char*)pl.wHideGangCount, sizeof(pl.wHideGangCount));
		bis.read((char*)pl.wHongzhongGangCount, sizeof(pl.wHongzhongGangCount));
		bis.read((char*)pl.wFaCaiGangCount, sizeof(pl.wFaCaiGangCount));
		bis.read((char*)pl.wMagicGangCount, sizeof(pl.wMagicGangCount));
		bis.read((char*)pl.wMagicOutCount, sizeof(pl.wMagicOutCount));
		bis.read((char*)pl.wMaxFSCount, sizeof(pl.wMaxFSCount));

		bis >> pl.wContractor;
		bis >> pl.bHardChiHu;
		bis >> pl.cbBigHuKind;

		bis.read((char*)pl.cbFengDingKind, sizeof(pl.cbFengDingKind));

		bis >> pl.cbTheOrder;
		bis >> pl.cbEndStatus;

		return bis;
	}
};

//任务命令
struct CMD_S_GAMEENDTASK
{
	bool							bTaskFinished[5];					//5星完成情况
	int								nPointNumCount;						//完成3星获得贝壳数
	int								nWinner;							//赢家
};

//海底提示
struct CMD_S_HD
{
	enum {XY_ID = SUB_S_HD_CHANGE}; 

	WORD							wTargetUser;						//下一个赌海底用户
	//bool							bIsCanHD;							//能否赌海底	
	tagCard							HDCard;								//被选过的海底牌

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_S_HD() { reset(); }
	friend bostream& operator<<(bostream& bos,const CMD_S_HD& pl)
	{
		bos << pl.wTargetUser;
		bos << pl.HDCard;

		return bos;
	}
	friend bistream& operator>>(bistream& bis,CMD_S_HD& pl)
	{
		pl.reset();
		bis >>  pl.wTargetUser;

		bis >>  pl.HDCard;

		return bis;
	}
};

//////////////////////////////////////////////////////////////////////////
//客户端命令结构

#define SUB_C_OUT_CARD				1									//出牌命令
#define SUB_C_OPERATE_CARD			2									//操作扑克
#define SUB_C_HD			        3									//海底操作
#define SUB_C_TRUSTEE				4									//托管操作
#define SUB_C_FUNSOUND				5									//聊天操作
#define SUB_C_HUANZHUO				6									//换桌操作
#define SUB_C_GOON_NEXT_GAME		7									//下一局

struct CMD_C_GoOnNextGame   // 一局完成后点击再来一局
{
	enum {XY_ID = SUB_C_GOON_NEXT_GAME};
	unsigned int userId;

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_C_GoOnNextGame(){reset();}

	friend bostream& operator<<(bostream& bos,const CMD_C_GoOnNextGame& pl)
	{
		bos << pl.userId;

		return  bos;
	}

	friend bistream& operator>>(bistream& bis,CMD_C_GoOnNextGame& pl)
	{
		pl.reset();
		bis >> pl.userId;

		return bis;
	}
};

//出牌命令
struct CMD_C_OutCard
{
	enum {XY_ID = SUB_C_OUT_CARD};
	BYTE							cbCardData;							//扑克数据
	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_C_OutCard(){reset();}

	friend bostream& operator<<(bostream& bos,const CMD_C_OutCard& pl)
	{
		bos << pl.cbCardData;

		return  bos;
	}

	friend bistream& operator>>(bistream& bis,CMD_C_OutCard& pl)
	{
		pl.reset();
		bis >> pl.cbCardData;

		return bis;
	}
};

//准备命令
struct CMD_C_SendReady
{
	bool							bIsGo;								//是否继续
};

//操作命令
struct CMD_C_OperateCard
{
	enum {XY_ID = SUB_C_OPERATE_CARD};
	BYTE							cbOperateCode;						//操作类型
	BYTE							cbOperateCard;						//操作扑克

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_C_OperateCard(){reset();}

	friend bostream& operator<<(bostream& bos,const CMD_C_OperateCard& pl)
	{
		bos << pl.cbOperateCode;
		bos << pl.cbOperateCard;

		return  bos;
	}

	friend bistream& operator>>(bistream& bis,CMD_C_OperateCard& pl)
	{
		pl.reset();
		bis >> pl.cbOperateCode;
		bis >> pl.cbOperateCard;

		return bis;
	}
};

//用户托管
struct CMD_C_Trustee
{
	enum {XY_ID = SUB_C_TRUSTEE};
	bool							bTrustee;							//是否托管	
	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_C_Trustee(){reset();}

	friend bostream& operator<<(bostream& bos,const CMD_C_Trustee& pl)
	{
		bos << pl.bTrustee;

		return  bos;
	}

	friend bistream& operator>>(bistream& bis,CMD_C_Trustee& pl)
	{
		pl.reset();
		bis >> pl.bTrustee;

		return bis;
	}
};

//海底操作
struct CMD_C_HD
{
	enum {XY_ID = SUB_C_HD};
	tagCard							HDCard;								//选择的海底牌

	void reset() { memset(this, 0, sizeof(*this)); }
	CMD_C_HD(){reset();}

	friend bostream& operator<<(bostream& bos,const CMD_C_HD& pl)
	{
		bos << pl.HDCard;

		return  bos;
	}

	friend bistream& operator>>(bistream& bis,CMD_C_HD& pl)
	{
		pl.reset();
		bis >> pl.HDCard;

		return bis;
	}
};

//发送趣语操作
struct CMD_C_FUNSOUND
{
	tagFunSound						FunSound;							//选择的趣语和语言种类
	char							szChatMessage[MAX_CHAT_LEN];		//聊天信息
};

//任务类型
enum enHZLZTaskKind
{
	enTask1 = 0,
	enTask2,
	enTask3,
	enTask4,
	enTask5,
};

//任务命令
struct tagHZLZTaskInfo
{
	int								nTaskIndex;							//任务索引
	char							szAction[128];						//动作描述
	int								nPointNum;							//奖励数目
	int								nTicketNum;							//门票数目
	enHZLZTaskKind					cbTaskType;							//任务类型
};
//////////////////////////////////////////////////////////////////////////
//#pragma pack()
#endif